package com.qingzhuge.service;

import com.qingzhuge.entity.BaseBean;
import com.qingzhuge.common.DtoConverter;
import com.qingzhuge.utils.PageUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;


/**
 * @author : zero.xiao
 * @description :  基础业务接口
 * @modified :
 */
public interface IBaseService<T extends BaseBean, ID extends Serializable> {

    Long count();

    Long count(T entity);

    boolean existsById(ID id);

    boolean exists(T entity);

    T findById(ID id);

    /**
     * 按对象信息查询一个对象
     * @param entity 对象信息
     * @return 对象
     */
    T findOne(T entity);

    PageUtil<T> query(T entity);

    List<T> findAll();

    List<T> findAll(Sort sort);

    List<T> findAll(T entity);

    List<T> findAll(T entity, Sort sort);

    List<T> findAllById(Iterable<ID> ids);

    @Transactional(rollbackFor = Exception.class)
    T save(T entity);

    @Transactional(rollbackFor = Exception.class)
    void deleteById(ID id);

    @Transactional(rollbackFor = Exception.class)
    void delete(T entity);

    /**获取随机数*/
    default String randomNumber(int count){
        return RandomStringUtils.random(count,false,true);
    }

    /**
     * 对象转dto
     * @param bean 数据对象实体
     * @param dto dto class
     * @param <B> 数据对象
     * @param <D> dto对象
     * @return dto
     */
    default <B,D> D bean2Dto(B bean, Class<D> dto){
        return new DtoConverter(){
            private static final long serialVersionUID = -9217345702624868520L;
        }.doBackward(bean, dto);
    }

    /**
     * 一个dto转为另一个dto
     * @param b 数据对象实体
     * @param obj dto class
     * @param <B>dto 数据对象
     * @param <D>dto 目标对象
     * @return dto
     */
    default <B,D> D obj2obj(B b, Class<D> obj){
        return new DtoConverter(){
            private static final long serialVersionUID = -5073687345217896762L;
        }.doBackward(b, obj);
    }

    /**
     * dto to bean
     * @param dto dto
     * @param <D> dto bean
     * @return data bean
     */
    <D> T dto2Bean(D dto);
}
